package ru.arriah.servicedesk.help;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MailSender {

   public class DefaultAuthenticator extends Authenticator {
      private PasswordAuthentication authentication;

      public DefaultAuthenticator(
         String userName, 
         String password
      ) {
         this.authentication = 
            new PasswordAuthentication(userName, password);
      }

      protected PasswordAuthentication getPasswordAuthentication() {
         return this.authentication;
      }
   }

   private String smtpPort;
   private String hostName;
   private String from;
   private String proto;
   private String subject;
   private String content;
   private Authenticator authenticator;
   private String charset;
   private String recipient;
   private Collection<InternetAddress> recipients;
   private Session session;

   public MailSender() {
      super();
      this.proto = "smtp";
      this.smtpPort = "25";
      recipients = new ArrayList<InternetAddress>();
   }

   public String getRecipient() {
      return recipient;
   }

   public void setRecipient(String recipient) {
      this.recipient = recipient;
   }

   public String getCharset() {
      return charset;
   }

   public void setCharset(String charset) {
      this.charset = charset;
   }

   public InternetAddress getFromAddress() throws AddressException {
      return new InternetAddress(this.from);
   }

   public InternetAddress getRecipientAddress() throws AddressException {
      return new InternetAddress(this.recipient);
   }

   public Authenticator getAuthenticator() {
      return authenticator;
   }

   public void setAuthenticator(Authenticator authenticator) {
      this.authenticator = authenticator;
   }

   public String getContent() {
      return content;
   }

   public void setContent(String content) {
      this.content = content;
   }

   public String getFrom() {
      return from;
   }

   public void setFrom(String from) {
      this.from = from;
   }

   public String getHostName() {
      return hostName;
   }

   public void setHostName(String hostName) {
      this.hostName = hostName;
   }

   public String getProto() {
      return proto;
   }

   public String getSmtpPort() {
      return smtpPort;
   }

   public void setSmtpPort(String smtpPort) {
      this.smtpPort = smtpPort;
   }

   public String getSubject() {
      return subject;
   }

   public void setSubject(String subject) {
      this.subject = subject;
   }

   public void setAuthentication(String userName, String password) {
      this.authenticator = new DefaultAuthenticator(userName, password);
      this.setAuthenticator(this.authenticator);
   }

   public void addRecipient(String recipient) throws Exception {
      recipients.add(new InternetAddress(recipient));
   }

   protected InternetAddress[] toInternetAddressArray(
      Collection<InternetAddress> collection) {
      InternetAddress[] ia = (InternetAddress[]) collection
         .toArray(new InternetAddress[collection.size()]);
      return ia;
   }

   public void send() throws Exception {
      try {
         Properties mailProperties = new Properties();

         mailProperties.put("mail.transport.protocol", this.proto);

         if (this.hostName != null) {
            mailProperties.put("mail.host", this.hostName);
         } else
            throw new Exception("Host required");

         mailProperties.put("mail.smtp.port", this.smtpPort);

         if (this.authenticator != null) {
            mailProperties.put("mail.smtp.auth", "true");
            this.session = Session.getInstance(mailProperties, authenticator);
         } else {
            mailProperties.put("mail.smtp.auth", "false");
            this.session = Session.getInstance(mailProperties);
         }

         MimeMessage message = new MimeMessage(session);

         if (this.from != null) {
            message.setFrom(this.getFromAddress());
         } else
            throw new Exception("Sender address required");

         if (!this.recipients.isEmpty()) {
            message.setRecipients(Message.RecipientType.TO, this
               .toInternetAddressArray(this.recipients));
         } else
            throw new Exception("Recipient address required");

         if (this.subject != null) {
            message.setSubject(this.subject, this.charset);
         } else
            throw new Exception("subject required");

         if (this.content != null) {
            message.setText(this.content, this.charset);
         } else
            throw new Exception("content required");

         Transport.send(message);

      } catch (Exception e) {
         e.printStackTrace();
         throw new Exception("Sending failed");
      }
   }
}